/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.admin.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.modules.admin.dto.BuildingUserDTO;
import org.springblade.modules.admin.dto.building.BuildingUserElevatorDTO;
import org.springblade.modules.admin.entity.*;
import org.springblade.modules.admin.enums.ElevatorMaintainStatusEnums;
import org.springblade.modules.admin.service.IBuildingContractPlusService;
import org.springblade.modules.admin.service.IElevatorContractService;
import org.springblade.modules.admin.service.IElevatorExtService;
import org.springblade.modules.admin.vo.BuildingUserVO;
import org.springblade.modules.admin.mapper.BuildingUserMapper;
import org.springblade.modules.admin.service.IBuildingUserService;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.modules.admin.vo.ElevatorDossierVO;
import org.springblade.modules.admin.vo.ProjectVO;
import org.springblade.modules.admin.vo.building.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 项目使用单位 服务实现类
 *
 * @author ysq
 * @since 2023-08-09
 */
@Service
public class BuildingUserServiceImpl extends BaseServiceImpl<BuildingUserMapper, BuildingUser> implements IBuildingUserService {

	@Autowired
	@Lazy
	private IBuildingContractPlusService buildingContractPlusService;

	@Autowired
	private IElevatorExtService elevatorExtService;

	@Autowired
	private IElevatorContractService elevatorContractService;

	@Override
	public IPage<BuildingUserVO> list(BuildingUserDTO buildingUser) {
		if (buildingUser.getBuildingUserType() == null) {
			buildingUser.setBuildingUserType(1);
		}
		Query query = new Query();
		query.setSize(buildingUser.getSize());
		query.setCurrent(buildingUser.getCurrent());
		IPage<BuildingUserVO> page = Condition.getPage(query);
		List<BuildingUserVO> list = baseMapper.selectBuildingUserPage(buildingUser.getSize() != 0 ? page : null, buildingUser);
		page.setRecords(list);
		return page;
	}

	@Override
	public IPage<ProjectVO> buildDingList(BuildingUserDTO buildingUserDTO) {
		Query query = new Query();
		query.setSize(buildingUserDTO.getSize());
		query.setCurrent(buildingUserDTO.getCurrent());
		IPage<ProjectVO> page = Condition.getPage(query);
		List<ProjectVO> list = baseMapper.buildDingList(page, buildingUserDTO);
		page.setRecords(list);
		return page;
	}

	@Override
	public IPage<ElevatorDossierVO> elevatorList(BuildingUserDTO buildingUserDTO) {
		Query query = new Query();
		query.setSize(buildingUserDTO.getSize());
		query.setCurrent(buildingUserDTO.getCurrent());
		IPage<ElevatorDossierVO> page = Condition.getPage(query);
		List<ElevatorDossierVO> list = baseMapper.elevatorList(buildingUserDTO.getSize() == 0 ? null : page, buildingUserDTO);
		page.setRecords(list);
		return page;
	}

	@Override
	public Boolean isDelete(Long id) {
		List<BuildingContractPlus> list = buildingContractPlusService.list(Wrappers.<BuildingContractPlus>lambdaQuery().eq(BuildingContractPlus::getCustomerUnitId, id));
		if (list.size() > 0) {
			return true;
		}
		List<ElevatorExt> extList1 = elevatorExtService.list(Wrappers.<ElevatorExt>lambdaQuery().eq(ElevatorExt::getBuildingUserId, id));
		if (extList1.size() > 0) {
			return true;
		}
		List<ElevatorExt> extList2 = elevatorExtService.list(Wrappers.<ElevatorExt>lambdaQuery().eq(ElevatorExt::getBuildingUserExtId, id));
		if (extList2.size() > 0) {
			return true;
		}
		return false;
	}

	@Override
	public List<BuildingUser> selectList(BuildingUser buildingUser) {
		return baseMapper.selectBuildingUserList(buildingUser);
	}

	@Override
	public BuildingUserStatusVo getBuildingUserStatus(Long id) {
		List<MaintainPlanConfig> list = baseMapper.getBuildingUserStatus(id, null);
		BuildingUserStatusVo buildingUserStatusVo = new BuildingUserStatusVo();

		//合作中的信息
		List<MaintainPlanConfig> inTimeElevatorCount = list.stream().filter(o -> o.getElevatorId() != null && !o.getMaintainStatus().equals(ElevatorMaintainStatusEnums.NO_STATUS.getId()) && !o.getMaintainStatus().equals(ElevatorMaintainStatusEnums.RELEASE_INSURANCE.getId())).collect(Collectors.toList());
		List<Long> inTimeUserCount = inTimeElevatorCount.stream().filter(o -> o.getBuildingUserId() != null).map(MaintainPlanConfig::getBuildingUserId).distinct().collect(Collectors.toList());
		List<Long> inTimeBuildingCount = inTimeElevatorCount.stream().filter(o -> o.getBuildingId() != null).map(MaintainPlanConfig::getBuildingId).distinct().collect(Collectors.toList());
		buildingUserStatusVo.setInTimeElevatorCount(inTimeElevatorCount.size());
		buildingUserStatusVo.setInTimeBuildingCount(inTimeBuildingCount.size());
		buildingUserStatusVo.setInTimeUserCount(inTimeUserCount.size());

		//丢保客户
		List<MaintainPlanConfig> dbBuildingList = list.stream().filter(o -> o.getElevatorId() != null && Convert.toInt(o.getMaintainStatus(), -2).equals(ElevatorMaintainStatusEnums.RELEASE_INSURANCE.getId())).collect(Collectors.toList());
		List<Long> dbUserCount = dbBuildingList.stream().filter(o -> o.getBuildingUserId() != null).map(MaintainPlanConfig::getBuildingUserId).distinct().collect(Collectors.toList());
		List<Long> dbBuildingCount = dbBuildingList.stream().filter(o -> o.getBuildingId() != null).map(MaintainPlanConfig::getBuildingId).distinct().collect(Collectors.toList());
		List<Long> dbElevatorCount = dbBuildingList.stream().filter(o -> o.getElevatorId() != null).map(MaintainPlanConfig::getElevatorId).distinct().collect(Collectors.toList());
		buildingUserStatusVo.setDbBuildingCount(dbBuildingCount.size());
		buildingUserStatusVo.setDbElevatorCount(dbElevatorCount.size());
		buildingUserStatusVo.setDbUserCount(dbUserCount.size());

		//全部客户
		List<Long> allBuildingIds = list.stream().filter(o -> o.getBuildingId() != null).map(MaintainPlanConfig::getBuildingId).distinct().collect(Collectors.toList());
		List<Long> allElevatorCount = list.stream().filter(o -> o.getElevatorId() != null).map(MaintainPlanConfig::getElevatorId).distinct().collect(Collectors.toList());
		buildingUserStatusVo.setAllBuildingCount(allBuildingIds.size());
		buildingUserStatusVo.setAllElevatorCount(allElevatorCount.size());
		buildingUserStatusVo.setAllUserCount(list.stream().map(MaintainPlanConfig::getBuildingUserId).distinct().collect(Collectors.toList()).size());
		return buildingUserStatusVo;
	}

	@Override
	public IPage<BuildingUserPageVo> pageV2(BuildingUserDTO buildingUserDTO) {
		Query query = new Query();
		query.setSize(buildingUserDTO.getSize());
		query.setCurrent(buildingUserDTO.getCurrent());
		IPage<BuildingUserPageVo> page = Condition.getPage(query);
		List<BuildingUserPageVo> list = baseMapper.pageV2(query.getSize() == 0 ? null : page, buildingUserDTO);
		Map<Long, List<MaintainPlanConfig>> listMap = baseMapper.getBuildingUserStatus(null, null).stream().collect(Collectors.groupingBy(MaintainPlanConfig::getBuildingUserId));
		for (BuildingUserPageVo buildingUserPageVo : list) {
			//type 客户类型2:暂无合同,1:合作客户0:潜在客户
			if (StrUtil.isEmpty(buildingUserPageVo.getMaintainStatus())) {
				buildingUserPageVo.setType(2);
			} else if (buildingUserPageVo.getMaintainStatus().contains(Convert.toStr(ElevatorMaintainStatusEnums.CONTRACT_IN_TIME.getId())) || buildingUserPageVo.getMaintainStatus().contains(Convert.toStr(ElevatorMaintainStatusEnums.CONTRACT_OUT_TIME.getId())) || buildingUserPageVo.getMaintainStatus().contains(Convert.toStr(ElevatorMaintainStatusEnums.DIS_ENABLE.getId())) || buildingUserPageVo.getMaintainStatus().contains(Convert.toStr(ElevatorMaintainStatusEnums.OUT_TIME_STOP.getId())) || buildingUserPageVo.getMaintainStatus().contains(Convert.toStr(ElevatorMaintainStatusEnums.OUT_TIME_END.getId())) || buildingUserPageVo.getMaintainStatus().contains(Convert.toStr(ElevatorMaintainStatusEnums.OUT_TIME_END_HAS_NEXT.getId()))) {
				buildingUserPageVo.setType(1);
			} else {
				buildingUserPageVo.setType(0);
			}
			List<MaintainPlanConfig> maintainPlanConfigs = listMap.get(buildingUserPageVo.getId());
			if (maintainPlanConfigs != null && maintainPlanConfigs.size() > 0) {
				if (maintainPlanConfigs.get(0).getElevatorId() != null) {
					//服务中
					List<Long> buildingIds = maintainPlanConfigs.stream().filter(o -> !o.getMaintainStatus().equals(ElevatorMaintainStatusEnums.NO_STATUS.getId()) && !o.getMaintainStatus().equals(ElevatorMaintainStatusEnums.RELEASE_INSURANCE.getId())).map(MaintainPlanConfig::getBuildingId).distinct().collect(Collectors.toList());
					List<Long> eleIds = maintainPlanConfigs.stream().filter(o -> !o.getMaintainStatus().equals(ElevatorMaintainStatusEnums.NO_STATUS.getId()) && !o.getMaintainStatus().equals(ElevatorMaintainStatusEnums.RELEASE_INSURANCE.getId())).map(MaintainPlanConfig::getElevatorId).distinct().collect(Collectors.toList());
					buildingUserPageVo.setInTimeBuildingCounts(buildingIds.size());
					buildingUserPageVo.setInTimeEleCounts(eleIds.size());
					//绑定所有的
					List<Long> builIds = maintainPlanConfigs.stream().map(MaintainPlanConfig::getBuildingId).distinct().collect(Collectors.toList());
					buildingUserPageVo.setAllBuildingCounts(builIds.size());
					buildingUserPageVo.setAllEleCounts(maintainPlanConfigs.size());

					//问题数
					buildingUserPageVo.setQuestionEleCounts(maintainPlanConfigs.stream().filter(o -> Convert.toInt(o.getIsQuestion(), 0) == 1 && o.getElevatorId() != null).map(MaintainPlanConfig::getElevatorId).distinct().collect(Collectors.toList()).size());
					buildingUserPageVo.setQuestionBuildingCounts(maintainPlanConfigs.stream().filter(o -> Convert.toInt(o.getIsQuestion(), 0) == 1 && o.getBuildingId() != null).map(MaintainPlanConfig::getBuildingId).distinct().collect(Collectors.toList()).size());

				}
			}
		}
		page.setRecords(list);
		return page;

	}

	@Override
	public BuildingUserElevatorVo elevatorStatus(Long id, Integer timeType) {
		BuildingUserElevatorVo buildingUserElevatorVo = new BuildingUserElevatorVo();
		List<MaintainPlanConfig> list = baseMapper.getBuildingUserStatus(id, timeType);

		for (MaintainPlanConfig config : list) {
			if (config.getMaintainStatus() == null) {
				config.setMaintainStatus(-2);
			}
		}
		//问题梯数
		Integer questionCounts = list.stream().filter(o -> Convert.toInt(o.getIsQuestion(), 0) == 1).collect(Collectors.toList()).size();

		//脱保梯数
		Integer tuoEleCounts = list.stream().filter(o -> o.getMaintainStatus() == ElevatorMaintainStatusEnums.OUT_TIME_STOP.getId() || o.getMaintainStatus() == ElevatorMaintainStatusEnums.OUT_TIME_END.getId() || o.getMaintainStatus() == ElevatorMaintainStatusEnums.OUT_TIME_END_HAS_NEXT.getId()).collect(Collectors.toList()).size();

		//断挡梯数
		Integer gapCounts = list.stream().filter(o -> Convert.toInt(o.getIsGap(), 0) > 0).collect(Collectors.toList()).size();

		//无合同梯数
		Integer noContractCounts = list.stream().filter(o -> o.getMaintainStatus() == ElevatorMaintainStatusEnums.DIS_ENABLE.getId()).collect(Collectors.toList()).size();

		//服务电梯数
		Integer inTimeElevatorCount = list.stream().filter(o -> o.getMaintainStatus() == ElevatorMaintainStatusEnums.CONTRACT_IN_TIME.getId() || o.getMaintainStatus() == ElevatorMaintainStatusEnums.CONTRACT_OUT_TIME.getId() || o.getMaintainStatus() == ElevatorMaintainStatusEnums.DIS_ENABLE.getId() || o.getMaintainStatus() == ElevatorMaintainStatusEnums.OUT_TIME_STOP.getId() || o.getMaintainStatus() == ElevatorMaintainStatusEnums.OUT_TIME_END.getId() || o.getMaintainStatus() == ElevatorMaintainStatusEnums.OUT_TIME_END_HAS_NEXT.getId()).collect(Collectors.toList()).size();

		Integer abInTimeElevatorCount = list.stream().filter(o -> o.getMaintainStatus() == ElevatorMaintainStatusEnums.CONTRACT_IN_TIME.getId() && Convert.toInt(o.getAboutEndDay(), 0) <= 90).collect(Collectors.toList()).size();

		//丢保电梯数
		Integer dbElevatorCount;
		if (timeType == 1) {
			dbElevatorCount = baseMapper.getBuildingUserStatus(id, 2).size();
		} else {
			dbElevatorCount = list.stream().filter(o -> o.getMaintainStatus() == ElevatorMaintainStatusEnums.RELEASE_INSURANCE.getId()).collect(Collectors.toList()).size();
		}
		buildingUserElevatorVo.setQuestionCounts(questionCounts);
		buildingUserElevatorVo.setTuoEleCounts(tuoEleCounts);
		buildingUserElevatorVo.setGapCounts(gapCounts);
		buildingUserElevatorVo.setNoContractCounts(noContractCounts);
		buildingUserElevatorVo.setInTimeElevatorCount(inTimeElevatorCount);
		buildingUserElevatorVo.setAbInTimeElevatorCount(abInTimeElevatorCount);
		buildingUserElevatorVo.setDbElevatorCount(dbElevatorCount);

		buildingUserElevatorVo.setAllElevatorCount(list.stream().filter(o -> o.getElevatorId() != null).collect(Collectors.toList()).size());
		return buildingUserElevatorVo;
	}

	@Override
	public IPage<BuildingUserElevatorDetailVo> elevatorListV2(BuildingUserElevatorDTO buildingUserElevatorDTO) {

		Query query = new Query();
		query.setSize(buildingUserElevatorDTO.getSize());
		query.setCurrent(buildingUserElevatorDTO.getCurrent());
		IPage<BuildingUserElevatorDetailVo> page = Condition.getPage(query);
		List<BuildingUserElevatorDetailVo> list = baseMapper.elevatorListV2(page, buildingUserElevatorDTO);
		for (BuildingUserElevatorDetailVo record : list) {
			if (record.getContractId() == null) {
				continue;
			}
			if (record.getStatus() == 1) {
				record.setAllStatusDesc("未审核");
			} else if (record.getContractStatus() == 1) {
				record.setAllStatusDesc("未生效");
			} else if (record.getContractStatus() == 2) {
				record.setAllStatusDesc("合同期内");
			} else if (record.getContractStatus() == 3) {
				record.setAllStatusDesc("合同到期");
			} else if (record.getContractStatus() == 4) {
				record.setAllStatusDesc("已终止");
			} else if (record.getContractExtStatus() == 5) {
				record.setAllStatusDesc("已作废");
			} else if (record.getStatus() == 3) {
				record.setAllStatusDesc("审核不通过");
			} else {
				record.setAllStatusDesc("-");
			}
		}
		page.setRecords(list);
		return page;
	}

	@Override
	public List<BuildingUserContractGapVo> getContractGap(Long elevatorId) {
		List<BuildingUserContractGapVo> resultList = new ArrayList<>(16);
		List<ElevatorContract> elevatorContracts = elevatorContractService.getListAll(elevatorId);
		elevatorContracts = beginTimeAsc(elevatorContracts);

		if (elevatorContracts.size() == 1) {
			return resultList;
		}

		for (int i = 0; i < elevatorContracts.size(); i++) {
			//当前合同
			ElevatorContract nowContract = elevatorContracts.get(i);
			//下一份合同
			Integer j = i;
			if (j < elevatorContracts.size() - 1) {
				j = j + 1;
			}
			ElevatorContract nextContract = elevatorContracts.get(j);
			if (nowContract.getContractId().equals(nextContract.getContractId())) {
				continue;
			}
			if (nextContract.getContractBeginTime().getTime() > nowContract.getContractEndTime().getTime()) {
				long days = DateUtil.betweenDay(nowContract.getContractEndTime(), nextContract.getContractBeginTime(), true);
				if (days > 1) {
					BuildingUserContractGapVo buildingUserContractGapVo = new BuildingUserContractGapVo();
					buildingUserContractGapVo.setBeginTime(nowContract.getContractEndTime());
					buildingUserContractGapVo.setEndTime(nextContract.getContractBeginTime());
					buildingUserContractGapVo.setBeginContractId(nowContract.getContractId());
					buildingUserContractGapVo.setEndContractId(nextContract.getContractId());
					buildingUserContractGapVo.setBeginContractNo(nowContract.getContractNo());
					buildingUserContractGapVo.setEndContractNo(nextContract.getContractNo());
					resultList.add(buildingUserContractGapVo);
				}
			}
		}
		return resultList;
	}


	private List<ElevatorContract> beginTimeAsc(List<ElevatorContract> elevatorContracts) {
		elevatorContracts = elevatorContracts.stream().sorted(new Comparator<ElevatorContract>() {
			@Override
			public int compare(ElevatorContract o1, ElevatorContract o2) {
				Date d1 = o1.getContractBeginTime();
				Date d2 = o2.getContractBeginTime();
				return d1.compareTo(d2);
			}
		}).collect(Collectors.toList());

		return elevatorContracts;
	}
}
